<?php

declare (strict_types = 1);

namespace App\Dao;

use App\Constants\ErrorCode;
use App\Exception\BusinessException;

/**
 * Dao公用方法
 * @Author czm
 * @DateTime 2020-05-27
 */
trait DaoTrait
{

    protected $driver = null; //model驱动
    protected $model = null; //model对象

    //切换model实例映射
    public function changeModel()
    {
        if ($this->driver instanceof \Hyperf\Database\Model\Model) {
            //手动注入model
            $this->model = $this->driver;
        } else {
            switch ($this->driver) {
                case 'App\Dao\AuthOrganizationDao':
                    $this->model = new \App\Model\AuthOrganization();
                    break;
                case 'App\Dao\AuthEmployeeDao':
                    $this->model = new \App\Model\AuthEmployee();
                    break;
                case 'App\Dao\AuthDutyDao':
                    $this->model = new \App\Model\AuthDuty();
                    break;
                case 'App\Dao\AuthCompanyDao':
                    $this->model = new \App\Model\AuthCompany();
                    break;
                case 'App\Dao\AuthPermissionDao':
                    $this->model = new \App\Model\AuthPermission();
                    break;
                case 'App\Dao\AuthAdminLogDao':
                    $this->model = new \App\Model\AuthAdminLog();
                    break;
                case 'App\Dao\AuthRoleDao':
                    $this->model = new \App\Model\AuthRole();
                    break;
                case 'App\Dao\AuthRolePermissionDao':
                    $this->model = new \App\Model\AuthRolePermission();
                    break;
                default:
                    throw new BusinessException(ErrorCode::ERR_BUESSUS, 'changeModel未注册无法映射');
            }
        }

    }

    /**
     * 根据条件获取对应总数
     * @Author czm
     * @DateTime 2020-05-26
     * @param array $map
     * @return void
     */
    public function countByWhereTrait($map = [])
    {
        $this->changeModel();
        return $this->model->when(!empty($map), function ($query) use ($map) {
            $query->where($map);
        })->count();
    }

    /**
     * 根据条件获取对应数据
     * @Author czm
     * @DateTime 2020-05-26
     * @param array $map
     * @return void
     */
    public function getByWhereTrait($map = [], $field = ["*"])
    {
        $this->changeModel();
        return $this->model->select($field)->when(!empty($map), function ($query) use ($map) {
            $query->where($map);
        })->get();
    }

    /**
     * 获取制定范围数据
     *
     * @Author czm
     * @DateTime 2020-11-04
     * @param string $key
     * @param array $whereIn
     * @param array $select
     * @return void
     */
    public function getWhereInKeyTrait(string $key, array $whereIn, array $select = ['*'])
    {
        $this->changeModel();
        return $this->model->whereIn($key, $whereIn)->select($select)->get()->toArray();
    }

    /**
     * 根据条件判断记录是否存在
     * @Author czm
     * @DateTime 2020-05-26
     * @param array $map
     * @return void
     */
    public function existsByWhereTrait($map = [])
    {
        $this->changeModel();
        return $this->model->when(!empty($map), function ($query) use ($map) {
            $query->where($map);
        })->exists();
    }

    /**
     * 新增内容
     * @Author czm
     * @DateTime 2020-05-27
     * @param [type] $data
     * @return void
     */
    public function createTrait($data)
    {
        $this->changeModel();
        return $this->model->create($data);
    }

    //根据id查找记录
    public function findTrait($id)
    {
        $this->changeModel();
        return $this->model->find($id);
    }

    //批量插入数据
    public function insertTrait($data)
    {
        $this->changeModel();
        return $this->model->insert($data);
    }

    public function insertGetIdTrait(array $data): int
    {
        $this->changeModel();
        return $this->model->insertGetId($data);
    }

    /**
     * 根据id更新内容
     * @Author czm
     * @DateTime 2020-05-27
     * @param [type] $data
     * @return void
     */
    public function updateByIdTrait($data)
    {
        $this->changeModel();
        $info = $this->findTrait($data['id']);
        if (empty($info)) {
            throw new BusinessException(ErrorCode::ERR_BUESSUS, '检测更新数据为空');
        }
        unset($data['id']);
        return $info->update($data);
    }

    /**
     * 根据条件查询first数据
     * @Author czm
     * @DateTime 2020-05-28
     * @return void
     */
    public function firstByWhereTrait(array $map, array $select = ['*'])
    {
        $this->changeModel();
        return $this->model->where($map)->select($select)->first();
    }

    /**
     * 根据条件删除数据
     * @Author czm
     * @DateTime 2020-05-28
     * @return void
     */
    public function deleteByWhereTrait($map)
    {
        $this->changeModel();
        return $this->model->where($map)->delete();
    }
    /**
     * 根据条件查询pluck数据
     * @Author czm
     * @DateTime 2020-05-28
     * @return void
     */
    public function pluckByWhereTrait($map, $field)
    {
        $this->changeModel();
        return $this->model->where($map)->pluck($field);
    }

    /**
     * 根据条件更新内容
     * @Author czm
     * @DateTime 2020-05-28
     * @param array $where
     * @param array $data
     * @return void
     */
    public function updateByWhereTrait($where = [], $data = [])
    {
        $this->changeModel();
        return $this->model->where($where)->update($data);
    }

    /**
     * 根据whereNotIn条件更新内容
     * @Author czm
     * @DateTime 2020-05-28
     * @param array $where
     * @param array $data
     * @return void
     */
    public function updateByWhereNotInTrait($where = [], $data = [])
    {
        $this->changeModel();
        return $this->model->whereNotIn($where)->update($data);
    }

    /**
     * 调用model fisrtOrCreate
     *
     * @Author czm
     * @DateTime 2020-07-04
     * @param [type] $data
     * @param array $map
     * @return void
     */
    public function firstOrCreateTrait($data, $map = [])
    {
        $this->changeModel();
        if (empty($map)) {
            return $this->model->firstOrCreate($data);
        } else {
            return $this->model->firstOrCreate($map, $data);
        }
    }

    /**
     * model自增字段 Trait
     *
     * @Author czm
     * @DateTime 2020-08-15
     * @param string $key
     * @param integer $value
     * @param array $map
     * @return void
     */
    public function incrementByWhereTrait(string $key, $value, $map = [])
    {
        $this->changeModel();
        return $this->model->where($map)->increment($key, $value);
    }

    /**
     * model自减字段 Trait
     *
     * @Author czm
     * @DateTime 2020-08-15
     * @param string $key
     * @param integer $value
     * @param array $map
     * @return void
     */
    public function decrementByWhereTrait(string $key, $value, $map = [])
    {
        $this->changeModel();
        return $this->model->where($map)->decrement($key, $value);
    }

    public function getArrayWhereInKey(string $key, array $whereIn, array $select = ['*'])
    {
        $this->changeModel();
        return $this->model->whereIn($key, $whereIn)->select($select)->get()->toArray();
    }
}
